package cn.itcast.service.cargo.impl;

import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductResult;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportDao exportDao;   //报运单dao

    @Autowired
    private ExportProductDao exportProductDao ; //报运单商品dao

    @Autowired
    private ExtEproductDao extEproductDao; //报运单附件dao

    @Autowired
    private ContractDao contractDao; //合同dao

    @Autowired
    private ContractProductDao contractProductDao; //合同货物dao

    @Autowired
    private ExtCproductDao extCproductDao; //合同附件dao


    /**
     * 新增报运单
     *  参数：export（报运单对象）
     *  字段：
     *      contractIds：页面勾选的所有合同id（多个之间用“，”拼接）
     *      customerContract：合同号集合（多个之间需要“ ”拼接）
     *      pro_num : 所有的货物数量
     *      ext_num ：所有的附件数量
     *   ContracProduct : 货物
     *      contractId:所属合同id
     *   ExportProduct : 报运单商品
     *      exportId: 商品所属的报运单id
     *   ExtCproduct : 合同附件
     *      contractProductId：所属的合同货物id
     *   ExtEprocuct ：报运单附件
     *      exportProductId ：所属的报运单商品id
     *      exportId: 所属的报运单id
     */
    public void save(Export export) {
      //a、保存报运单数据
        int proNum = 0;
        int extNum = 0;
        //1、设置主键id
        export.setId(UUID.randomUUID().toString());
        //2、根据合同id，查询所有勾选的购销合同
        String [] contractIds = export.getContractIds().split(","); //1,2
        String customerContract = "";
        for (String contractId : contractIds) {
            Contract contract = contractDao.selectByPrimaryKey(contractId);
            //3、拼接合同编号
            customerContract += contract.getContractNo() + " ";
            //4、更新合同状态  （由1--2：已报运）
            contract.setState(2);
            contractDao.updateByPrimaryKeySelective(contract);
        }
        export.setCustomerContract(customerContract);
      //b、保存报运单商品数据
        //1、根据合同id，查询当前合同下的所有货物 ： list
        ContractProductExample ce = new ContractProductExample();
        ContractProductExample.Criteria cc = ce.createCriteria();
        cc.andContractIdIn(Arrays.asList(contractIds));
        List<ContractProduct> cps = contractProductDao.selectByExample(ce);
        //2、循环所有货物
        for (ContractProduct cp : cps) {
            //3、一个货物对象，构造一个商品对象
            ExportProduct ep = new ExportProduct();
            BeanUtils.copyProperties(cp, ep); //将cp中的同名属性值，复制到ep对象中
            //4、设置商品id
            ep.setId(UUID.randomUUID().toString());
            //5、设置所属的报运单id
            ep.setExportId(export.getId());
            //6、保存商品到数据库中
            exportProductDao.insertSelective(ep);

            //c、保存报运单附件数据
            //1、根据货物id，查询此货物下的所有合同附件
            ExtCproductExample ece = new ExtCproductExample();
            ExtCproductExample.Criteria ecc = ece.createCriteria();
            ecc.andContractProductIdEqualTo(cp.getId());
            List<ExtCproduct> ecs = extCproductDao.selectByExample(ece);
            //2、循环合同附件
            for (ExtCproduct ec : ecs) {
                //3、一个合同附件，构造一个报运单附件
                ExtEproduct ee = new ExtEproduct();
                BeanUtils.copyProperties(ec, ee);
                //4、设置附件的id
                ee.setId(UUID.randomUUID().toString());
                //5、设置附件所属的商品id
                ee.setExportProductId(ep.getId());
                //6、设置附件所属的报运单id
                ee.setExportId(export.getId());
                //7、保存合同附件
                extEproductDao.insertSelective(ee);
            }
            extNum += ecs.size();
        }
        proNum = cps.size();
        //保存报运单
        export.setProNum(proNum);
        export.setExtNum(extNum);
        export.setState(0);
        exportDao.insertSelective(export);
    }

    @Override
    public void update(Export export) {
        //1、更新报运单
        exportDao.updateByPrimaryKeySelective(export);
        //2、循环报运单的每个商品
        if(export.getExportProducts() != null) {
            for (ExportProduct exportProduct : export.getExportProducts()) {
                //3、更新报运单商品
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }
    }

    @Override
    public void delete(String id) {

    }


    @Override
    public Export findById(String id) {
        return exportDao.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo findAll(ExportExample example, int page, int size) {
        PageHelper.startPage(page,size);
        List<Export> list = exportDao.selectByExample(example);
        return new PageInfo(list);
    }

    /**
     * 电子报运
     *  参数：报运单id
     */
    public void exportE(String id) {
        //1、根据报运单id，查询此次报运的报运单对象    Export
        Export export = exportDao.selectByPrimaryKey(id);
        //2、根据报运单id，查询此报运单下的所有商品    ExportProduct
        ExportProductExample example = new ExportProductExample();
        ExportProductExample.Criteria criteria = example.createCriteria();
        criteria.andExportIdEqualTo(id);
        List<ExportProduct> eps = exportProductDao.selectByExample(example);
        //3、将自己的Export构建为海关保运需要的ExportVO
        ExportVo evo = new ExportVo();
        BeanUtils.copyProperties(export, evo);
        evo.setExportId(id);
        //4、将自己的ExportProduct构建为海关需要的ExportProductVO
        List<ExportProductVo> epvos = new ArrayList<>();
        for (ExportProduct ep : eps) {
            ExportProductVo epvo = new ExportProductVo();
            BeanUtils.copyProperties(ep, epvo);
            epvo.setExportProductId(ep.getId());
            epvos.add(epvo);
        }
        evo.setProducts(epvos);
        //5、通过WebClient工具类将数据发送到海关，获取返回值
        WebClient webClient = WebClient.create("http://localhost:9001/ws/export/ep");
        Integer result = webClient.post(evo, Integer.class);//参数一：传递的对象，参数二：返回值类型
        //6、判断返回值是否=0，如果为0说明海关已经接受了数据，更新报运单状态！
        if(result == 0) {
            export.setState(2);
            exportDao.updateByPrimaryKeySelective(export);
        }
    }

    @Override
    public List findAll(ExportExample example) {
        return exportDao.selectByExample(example);
    }


    /**
     * 更新保运结果
     *  ExportResult : 海关响应的保运结果
     *      报运单主体信息
     *      list（所有的商品信息）
     *
     *   业务：
     *      1、更新报运单（更新状态）
     *      2、更新商品的关税
     */
    public void updateE(ExportResult result) {
        //a、更新报运单（更新状态）
        //1、根据id查询报运单
        Export export = exportDao.selectByPrimaryKey(result.getExportId());
        //2、设置状态和备注
        export.setState(result.getState());
        export.setRemark(result.getRemark());
        //3、更新报运单
        exportDao.updateByPrimaryKeySelective(export);
        //b、更新商品的关税
        if(result.getProducts() != null) {
            for (ExportProductResult product : result.getProducts()) {
                ExportProduct ep = exportProductDao.selectByPrimaryKey(product.getExportProductId());
                ep.setTax(product.getTax());
                exportProductDao.updateByPrimaryKeySelective(ep);
            }
        }
    }
}
